#ifndef _OBJ_H_
#define _OBJ_H_

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define BUILD_OBJ2(name, def, superDef, interface, superInterface) \
typedef struct \
{ \
  superDef \
  def \
} name; \
typedef struct \
{ \
  superInterface \
  interface \
} name##Interface; \
name##Interface *name##I();

#define ENTRY(f) . f = f

#define SETUP_IF(name, super, ...) \
name##Interface *name##I() { \
  static name##Interface iTmp = {__VA_ARGS__}; \
  static name##Interface iResult; \
  static char init = 0; \
  if(!init) { \
    init=1; \
    super##Interface *superI = super##I(); \
    memcpy(&iResult, superI, sizeof(super##Interface)); \
    void **src = (void **)&iTmp; \
    void **dst = (void **)&iResult; \
    int i; \
    for(i=0; i<sizeof(name##Interface); i+=4) { \
      if(!*dst) *dst = *src; \
      ++dst; ++src; \
    } \
  } \
  return &iResult; \
}

#define BUILD_OBJ(name,super) BUILD_OBJ2(name, name##_DEF, super##_DEF, name##_INTERFACE, super##_INTERFACE)

#define None_DEF
#define None_INTERFACE

#define Obj_DEF \
  void *interface;

#define Obj_INTERFACE \
  void (*init)(Obj *this);


BUILD_OBJ(Obj,None);

#endif
